{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# <center>RegEx in Python</center>\n",
    "\n",
    "![](images/memes/meme33.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Look behind\n",
    "\n",
    "\n",
    "**Look behind** mechanism checks the match for a non-consuming expression **behind** a given pattern.\n",
    "\n",
    "\n",
    "## Positive look behind\n",
    "\n",
    "- **Positive look behind** will succeed if the passed non-consuming expression **does match** against the forthcoming input.\n",
    "\n",
    "- The syntax is `(?<=B)A` where `A` is the **actual expression** and `B` is the **non-consuming expression**. \n",
    "\n",
    "\n",
    "Let's check out an example to understand the concept. Let's assume that we want to find a match for `regex` in the given text only if it is succeeded by `love` or `hate`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "from utils import highlight_regex_matches"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "txt = \"love regex or hate regex, can't ignore regex\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "pattern = re.compile(\"(?<=(love|hate)\\s)regex\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "love \u001b[43m\u001b[1mregex\u001b[0m or hate \u001b[43m\u001b[1mregex\u001b[0m, can't ignore regex\n"
     ]
    }
   ],
   "source": [
    "highlight_regex_matches(pattern, txt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Negative look behind\n",
    "\n",
    "- **Negative look behind** will succeed if the passed non-consuming expression **does not match** against the forthcoming input.\n",
    "\n",
    "- The syntax is `(?<!B)A` where `A` is the **actual expression** and `B` is the **non-consuming expression**. \n",
    "\n",
    "\n",
    "Let's assume that we want to find a match for `regex` in the given text if it is not followed by `love` or `hate`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "pattern = re.compile(\"(?<!(love|hate)\\s)regex\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "love regex or hate regex, can't ignore \u001b[43m\u001b[1mregex\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "highlight_regex_matches(pattern, txt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](images/memes/meme34.jpg)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
